<?php namespace sacvoyage\http;

require_once('sacvoyage/http/util.php');
require_once('sacvoyage/http/I18n.php');
use \sacvoyage\http\parse_path;

use \sacvoyage\http\Globals;
use sacvoyage\domain\Domain;
use sacvoyage\Object;
use sacvoyage\domain\Synchronizer;


class Site {
	
	public function __construct(Domain $domain) {
		$this->_domain=$domain;
		
		// TODO: remove this spike
		
		/*$root=$this->_domain->loadUser('root');
		$configs=$root->getProperty()->getCollection('sys.user.accounts');
		$configs->write(array(new Object(array(
			'_id'=>'alex', 'password'=>'123'
		))));*/
		
	}
	
	public function serve($path) {
		try {
			$this->_doServe($path);	
		} catch (JSONException $e) {
			if(!headers_sent()) {
				header($_SERVER["SERVER_PROTOCOL"]." 400 Bad Request", true);
			}
			echo '{"status":"error","message":"'.$e->getMessage().'"}';
		}
	}
	
	private $_domain;
	private $_isSignupEnabledValue=null;
	
	/// serve the request
	private function _doServe($path) {
		# @-workaround to prevent:
		# Notice: session_start(): ps_files_cleanup_dir: opendir(/var/lib/php5) failed: 
		# Permission denied (13) in ...
		@session_start(); 
		list($path, $rest)=parse_path($path);
		
		// user logged in and browsing own property
		if(isset($_SESSION['user']) && ($path==$_SESSION['user'])) {
			$user=$this->_domain->loadUser($_SESSION['user']);
			Globals::setResourceName($user->getName());
			$resource=new Resource($user->getProperty());
			$resource->serve($rest);
		}
		
		// user logged in and browsing sacvoyage root
		elseif(isset($_SESSION['user']) && !$path) {
			Globals::redirect($_SESSION['user']);
		}
		
		// give opportunity to log in
		elseif($this->_login($path)) {
			// _login makes all
		}
		
		// give opportunity to log register
		elseif($this->_signup($path)) {
			// _login makes all
		}
		// existing share requested
		elseif(false /* request shared resource (not implemented yet)*/) {
			// user not logged in or browsing outside his own property 
			echo "shares not implemented yet";
		} 
		
		// any other unknown path
		else {
			if(!headers_sent()) {
				header($_SERVER["SERVER_PROTOCOL"]." 404 Not found", true);
			}
			// TODO: make nice not found page
			global $CONFIG;
			$show_signup=$this->_isSignupEnabled();
			$login_error=\sacvoyage\http\i18n('page not found');
			include('sacvoyage/templates/login.php');
		}
	}

	// returns true if this query has to do with logging in
	private function _login($path) {
	
		// maybe attempt to login
		if(strtoupper($_SERVER['REQUEST_METHOD'])=='POST') {
			if(isset($_POST['action']) && $_POST['action']=='signup' 
			&& $this->_isSignupEnabled()) {
				return false;
			}
			
			// if there was attemt to login
			if(!$path && isset($_POST['user']) && isset($_POST['password'])) {
				$user=$this->_domain->login($_POST['user'], $_POST['password']);
			} elseif($path && isset($_POST['password'])) {
				$user=$this->_domain->login($path, $_POST['password']);
			} 
			// there was no attemt to login
			else {
				return false;
			}
	
			
			if($user) {
				$_SESSION['user']=$user->getName();
				Globals::redirect('/'.$user->getName());
				global $CONFIG;
				echo '{"status":"ok","message":"Your sacvoyage, '.$user->getName().'"}';
			} else {
				$_SESSION['user']=null;
				header($_SERVER["SERVER_PROTOCOL"]." 403 Forbidden", true);
				
				if(!$path) { // most likely human-login
					global $CONFIG;
					$show_form='login';
					$show_signup=$this->_isSignupEnabled();
					$login_error=i18n('invalid user name and/or password');
					$shakeHead=true;
					include 'sacvoyage/templates/login.php';
				} else {   // most likely robot-login
					echo '{"status": "error", "message": "invalid user name or password"}';
				}
				
			}
			return true;
		} 
		// just show login form
		elseif(!$path) {
			global $CONFIG;
			$show_signup=$this->_isSignupEnabled();
			$show_form='login';
			include 'sacvoyage/templates/login.php';
			return true;
		} 
		// there was some other request
		else {
			return false;
		}
	}

	
	private function _signup($path) {
		// maybe attempt to signup
		if(strtoupper($_SERVER['REQUEST_METHOD'])=='POST'
		&& $this->_isSignupEnabled()
		&& !$path 
		&& isset($_POST['action']) && $_POST['action']=='signup' ) {
				
			if(isset($_POST['user'])     && $_POST['user'] 
			&& isset($_POST['password']) && $_POST['password']) {
				$root=$this->_domain->loadUser('root');
				$sys_user_accounts=$root->getProperty()->getCollection('sys.user.accounts');
				$config=$sys_user_accounts->read($_POST['user']);
				if(!$config) {
					$userName=$_POST['user'];
					
					$sys_user_accounts->write(
						new Object(array(
							'_id'=>$userName,
							'password'=>$_POST['password']
						))
					);
					
					// copy all data from prototype
					$prototype=$this->_domain->loadUser('alex')->getProperty();
					$target=$this->_domain->loadUser($userName)->getProperty();
					$synchronizer=new Synchronizer(
						$prototype, 
						$target,
						new Object(array('mode'=>'push')) 
					);
					$synchronizer->synchronize();
					
					$_SESSION['user']=$userName;
					//Globals::redirect('/'.$userName); !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
					return true;
				} else {
					$signup_error=i18n('user already exists');
				}
			} else {
				$signup_error=i18n('user name and password must be specified');
			}
			
			global $CONFIG;
			$show_signup=true;
			$show_form='signup';
			$shakeHead=true;
			include 'sacvoyage/templates/login.php';
			return true;
		}
		return false;
	}

	private function _isSignupEnabled() {
		if($this->_isSignupEnabledValue===null) {
			$root=$this->_domain->loadUser('root');
			$config=$root->getProperty()->getCollection('sys.cfg')->read('signup');
			$this->_isSignupEnabledValue=!($config && isset($config->enabled) && !$config->enabled);
		}
		return $this->_isSignupEnabledValue;
	}
	
	
}


?>
